#include <stdio.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_pwm.h"
#include "hi_io.h"
#include "hi_pwm.h"
#include "hi_time.h"

// 音符频率分频值（40MHz时钟）
static const uint16_t g_tuneFreqs[] = {
    0,
    38223, // 1 高音Do
    34052, // 2 高音Re
    30338, // 3 高音Mi
    28635, // 4 高音Fa
    25511, // 5 高音So
    22728, // 6 高音La
    20249, // 7 高音Si
    51021, // 8 中音So
};

// 《两只老虎》简谱
static const uint8_t g_scoreNotes[] = {
    1, 2, 3, 1, 1, 2, 3, 1, 3, 4, 5, 3, 4, 5,
    5, 6, 5, 4, 3, 1, 5, 6, 5, 4, 3, 1, 1, 8, 1, 1, 8, 1,
};

// 音符时值（单位：拍）
static const uint8_t g_scoreDurations[] = {
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 8,
    3, 1, 3, 1, 4, 4, 3, 1, 3, 1, 4, 4, 4, 4, 8, 4, 4, 8,
};

// 初始化函数
static void beepInit(void) {
    hi_gpio_init(); 
    // 【修改】设置 GPIO 11 引脚复用为 PWM2 输出
    hi_io_set_func(HI_IO_NAME_GPIO_11, HI_IO_FUNC_GPIO_11_PWM2_OUT); 
    // 【修改】初始化 PWM2 端口
    hi_pwm_init(HI_PWM_PORT_PWM2); 
    hi_pwm_set_clock(PWM_CLK_XTAL); 
}

// 播放任务
static void beepSingTask(void *arg) {
    (void)arg;
    beepInit();

    for (size_t i = 0; i < sizeof(g_scoreNotes) / sizeof(g_scoreNotes[0]); i++) {
        uint8_t note = g_scoreNotes[i];
        
        if (note >= (sizeof(g_tuneFreqs) / sizeof(g_tuneFreqs[0]))) {
            printf("Error: Note index %d out of bounds!\n", note);
            continue;
        }
        
        uint16_t freqDiv = g_tuneFreqs[note];
        uint32_t duration = g_scoreDurations[i] * (125 * 1000);

        printf("Note: %d, FreqDiv: %d, Duration: %lu\n", note, freqDiv, duration);

        if (note > 0)
        {
            // 【修改】使用 PWM2 端口
            hi_pwm_start(HI_PWM_PORT_PWM2, freqDiv / 2, freqDiv);
            hi_udelay(duration);
            // 【修改】使用 PWM2 端口
            hi_pwm_stop(HI_PWM_PORT_PWM2);
        } else {
            hi_udelay(duration);
        }
        
        hi_udelay(50000);
    }
}

// 任务入口
static void BeepEntry(void) {
    osThreadAttr_t attr = {
        .name = "beepSingTask",
        .stack_size = 4096,
        .priority = osPriorityNormal,
    };
    if (osThreadNew(beepSingTask, NULL, &attr) == NULL) {
        printf("Failed to create beepSingTask!\n");
    }
}

SYS_RUN(BeepEntry);